home *** CD-ROM | disk | FTP | other *** search
/ MacTech 1 to 12 / MacTech-vol-1-12.toast / Source / MacTech® Magazine / Volume 12 - 1996 / 12.05 May 96 / Memory Madness / MemoryMadness.p next >
Encoding:
Text File  |  1996-02-15  |  4.9 KB  |  195 lines  |  [TEXT/CWIE]

  1. program MemoryMadness;
  2.  
  3.     uses
  4.         Memory, Resources, Files,
  5.         MemoryMadnessC;
  6.     
  7.     procedure DemonstratePointer;
  8.         var
  9.             data: Ptr;
  10.     begin
  11.         data := NewPtr( 1024 ); { allocate 1024 bytes }
  12.         if data <> nil then begin
  13.             writeln( 'NewPtr allocated 1024 bytes' );
  14.             { You now have 1024 bytes pointed to by data }
  15.             BlockMove( data, data, 1024 ); { do whatever }
  16.             DisposePtr( data ); { release the memory }
  17.             data := nil; { a good habit }
  18.         end else begin
  19.             writeln( 'NewPtr failed with error ', MemError );
  20.         end;
  21.     end;
  22.     
  23.     procedure DemonstrateHandle;
  24.         var
  25.             data: Handle;
  26.     begin
  27.         data := NewHandle( 1024 ); { allocate 1024 bytes }
  28.         if data <> nil then begin
  29.             writeln( 'NewHandle allocated 1024 bytes' );
  30.             { You now have 1024 bytes pointed to by data^ }
  31.             BlockMove( data^, data^, 1024 ); { do whatever }
  32.             DisposeHandle( data ); { release the memory }
  33.             data := nil; { a good habit }
  34.         end else begin
  35.             writeln( 'NewHandle failed with error ', MemError );
  36.         end;
  37.     end;
  38.     
  39.     procedure DontDemonstrateFakeHandle; { DO NOT DO THIS! }
  40.         var
  41.             data: Ptr;
  42.             fake: Handle;
  43.     begin
  44.         data := NewPtr( 1024 );
  45.         fake := @data; { fake is now a "fake handle" }
  46.         { under no circumstances should you pass this to a routine expecting a handle }
  47.         SetHandleSize( fake, 100 ); { THIS IS WRONG! }
  48.         DisposeHandle( fake ); { THIS IS WRONG! }
  49.     end;
  50.     
  51.     procedure DontDemonstrateWritingToMasterPointer; { DO NOT DO THIS! }
  52.         var
  53.             data: Ptr;
  54.             bad: Handle;
  55.     begin
  56.         data := NewPtr( 1024 );
  57.         if data <> nil then begin
  58.             bad := NewHandle( 2048 );
  59.             if bad <> nil then begin
  60.                 { ok so far, but not this }
  61.                 SetPtrSize( bad^, 200 ); { THIS IS WRONG! }
  62.                 bad^ := data; { THIS IS WRONG! }
  63.                 bad^ := Ptr(longint(bad^) + 10); { THIS IS WRONG! }
  64.                 DisposeHandle( bad ); { too late, it’s toast already }
  65.                 bad := nil; { too little to late }
  66.             end else begin
  67.                 writeln( 'DontDemonstrateWritingToMasterPointer failed with error ', MemError );
  68.             end;
  69.             DisposePtr( data );
  70.         end else begin
  71.             writeln( 'DontDemonstrateWritingToMasterPointer failed with error ', MemError );
  72.         end;
  73.     end;
  74.     
  75.     procedure DemonstrateMovingHandle;
  76.         var
  77.             master: Ptr;
  78.             data, other: Handle;
  79.     begin
  80.         data := NewHandle( 1024 );
  81.         if data <> nil then begin
  82.             other := NewHandle( 1024 );
  83.             if other <> nil then begin
  84.                 master := data^; { Danger!  If the memory manager is called, }
  85.                     { or indeed almost anything is called, master will be out of date }
  86.                 BlockMove(master, master, 1024 ); { safe, since BlockMove is known not to move memory }
  87.                 SetHandleSize( other, 512 ); { master is now out of date! }
  88.                 master := nil; { a good habit }
  89.                 HLock( data ); { dont let data move around in memory }
  90.                 master := data^;
  91.                 SetHandleSize( other, 256 ); { master is still guarenteed to be correct }
  92.                 BlockMove(master, master, 1024 ); { safe since master is still correct }
  93.                 DisposeHandle( other ); { release the memory }
  94.                 other := nil; { a good habit }
  95.             end;
  96.             DisposeHandle( data ); { release the memory }
  97.             data := nil; { a good habit }
  98.             master := nil; { master is no longer valid! }
  99.         end else begin
  100.             writeln( 'DemonstrateMovingHandle failed with error ', MemError );
  101.         end;
  102.     end;
  103.     
  104.     procedure DontDemonstrateFakePointerorHandle;
  105.     { Memory Madness point 2 }
  106.     
  107.     var
  108.         h:handle;
  109.         
  110.     begin
  111.         h := NewHandle( 10 );
  112.         SetPtrSize( h^, 20 );
  113.     end;
  114.     
  115.     procedure DoStuff(aPtr:Ptr;hsize:Size);
  116.     
  117.     begin
  118.         { A do nothing procedure }
  119.         aPtr:=aPtr;  {UNUSED}
  120.         hsize:=hsize;  {UNUSED}
  121.     end;
  122.     
  123.     procedure DontDemonstrateSetupData( data: Handle );
  124.     { Memory Madness point 6 }
  125.     
  126.     begin
  127.         HLock( data );
  128.         DoStuff( data^, GetHandleSize( data ) );
  129.         HUnlock( data );
  130.     end;
  131.  
  132.     procedure DemonstrateInitializeData( data: Handle );
  133.     { Memory Madness point 6 }
  134.     
  135.     var
  136.         state: SignedByte;
  137.     begin
  138.         state := HGetState( data );
  139.         HLock( data );
  140.         DoStuff( data^, GetHandleSize( data ) );
  141.         HSetState( data, state );
  142.     end;
  143.  
  144.     procedure DisposeAnything( var h: Handle );
  145.     begin
  146.         if h <> nil then begin
  147.             if HomeResFile( h ) <> -1 then begin
  148.                 ReleaseResource( h );
  149.             end else begin
  150.                 DisposeHandle( h );
  151.             end;
  152.             h := nil;
  153.         end;
  154.     end;
  155.     
  156.     procedure DemonstrateCloseResFile;
  157.     
  158.     var 
  159.         str1, str2,result:StringHandle;
  160.         resfile:integer;
  161.         spec:FSSpec;
  162.         oe:OSErr;
  163.         
  164.     begin
  165.         oe:=FSMakeFSSpec(0,0,'MemoryMadnessData.rsrc',spec);
  166.         if oe=noErr then begin
  167.             result := nil;
  168.             resfile := FSpOpenResFile( spec, fsRdPerm );
  169.             if resfile <> -1 then begin
  170.                 str1 := StringHandle(GetResource( 'STR ', 128 ));
  171.                 str2 := StringHandle(GetResource( 'STR ', 129 ));
  172.                 if (str1 <> nil) & (str2 <> nil) then begin
  173.                     if length(str1^^) > length(str2^^) then begin
  174.                         result := str1;
  175.                     end else begin
  176.                         result := str2;
  177.                     end;
  178.                     DetachResource( Handle(result));
  179.                 end;
  180.                 CloseResFile( resfile );
  181.             end;
  182.             
  183.             writeln(result^^);
  184.             DisposeHandle(Handle(result));
  185.         end;
  186.     end;
  187.     
  188. begin
  189.     writeln( 'Starting' );
  190.     DemonstratePointer;
  191.     DemonstrateHandle;
  192.     DemonstrateMovingHandle;
  193.     DemonstrateCloseResFile;
  194.     DoCStuff;
  195. end.